/*
 Source: ufxTrader.java
 Software Copyright: Hundsun Technologies Inc.
 System: UFX Future Demo (Asynchronous)
 Module: Package input parameter(Trading realated)
 Describition:
 This class is packing trading related input parameters for each function and send the package to the broker, the documents for function 
 description and Java programming helper can be found at ufx website: https://ufx.hscloud.cn/
 Function id include: 819706 ,819707,819709,819710,819711
 author: Kai Zhan
 Date:2016/05/12
 Others:
 This demo is a sample for using Hundsun UFX System, we are highly not recommand any user to use this demo at any real market，for more details 
 please read <T2SDK JAVA Developer Manual>
 */
package com.hmkj.core.api.ufx.trade;

import com.hundsun.t2sdk.common.core.context.ContextUtil;
import com.hundsun.t2sdk.common.share.dataset.DatasetService;
import com.hundsun.t2sdk.impl.client.T2Services;
import com.hundsun.t2sdk.interfaces.IClient;
import com.hundsun.t2sdk.interfaces.T2SDKException;
import com.hundsun.t2sdk.interfaces.share.dataset.IDataset;
import com.hundsun.t2sdk.interfaces.share.dataset.IDatasets;
import com.hundsun.t2sdk.interfaces.share.event.EventReturnCode;
import com.hundsun.t2sdk.interfaces.share.event.EventTagdef;
import com.hundsun.t2sdk.interfaces.share.event.EventType;
import com.hundsun.t2sdk.interfaces.share.event.IEvent;
import lombok.extern.slf4j.Slf4j;

/**
 * 异步返回数据
 */
@Slf4j
public class UfxTrade {

    private IClient client = null;
    private T2Services server = T2Services.getInstance();// 获取T2实例

    public void Init() throws Exception {
        log.info("ar_tree"); //用logger方式打印
        //ar_tree是配置在配置文件中的服务
        client = server.getClient("ar_tree");
    }
//异步登录打包

    public void ReqFunction819700(String AccountName, String Password) throws Exception {
        // 获取event
        IEvent event = ContextUtil.getServiceContext().getEventFactory()
                .getEventByAlias("819700", EventType.ET_REQUEST);
        // 往event中添加dataset
        IDataset dataset = DatasetService.getDefaultInstance().getDataset();
        dataset.addColumn("op_station");//站点地址
        dataset.addColumn("fund_account");//输入内容
        dataset.addColumn("password");//密码
        dataset.appendRow();
        dataset.updateString("op_station", "123456");
        dataset.updateString("fund_account", AccountName);
        dataset.updateString("password", Password);
        event.setServiceId("819700");//打入功能号
        event.putEventData(dataset);//入参打包
        event.setIntegerAttributeValue(EventTagdef.TAG_SENDERID, 5);//分配节点为5
        setEventHead(event, 91024);
        unPack(event, event.getServiceId()); //入参解包，同时打印发送包参数信息
        client.send(event);//发送包
    }

    //期货委托确认
    public void ReqFunction819706(String user_token, String futu_exch_type, String contract_code, String entrust_bs, String futures_direction, String hedge_type, String entrust_amount, String futu_entrust_price) throws Exception {
        // 获取event
        IEvent event = ContextUtil.getServiceContext().getEventFactory()
                .getEventByAlias("819706", EventType.ET_REQUEST);
        //往event中添加dataset
        IDataset dataset = DatasetService.getDefaultInstance().getDataset();
        dataset.addColumn("user_token");//用户口令
        dataset.addColumn("futu_exch_type");//交易类别
        dataset.addColumn("contract_code");//合约代码
        dataset.addColumn("entrust_bs");//买卖方向
        dataset.addColumn("futures_direction");//开平仓方向
        dataset.addColumn("hedge_type");//投机/套保类型
        dataset.addColumn("entrust_amount");//委托数量
        dataset.addColumn("futu_entrust_price");//委托价格
        dataset.addColumn("entrust_prop");//委托属性
        dataset.addColumn("entrust_reference");//委托引用
        dataset.appendRow();
        dataset.updateString("user_token", user_token);
        dataset.updateString("futu_exch_type", futu_exch_type);
        dataset.updateString("contract_code", contract_code);
        dataset.updateString("entrust_bs", entrust_bs);
        dataset.updateString("futures_direction", futures_direction);
        dataset.updateString("hedge_type", hedge_type);
        dataset.updateString("entrust_amount", entrust_amount);
        dataset.updateString("futu_entrust_price", futu_entrust_price);
        dataset.updateString("entrust_prop", "");
        dataset.updateString("entrust_reference", "");
        event.setServiceId("819706");//打入功能号
        event.putEventData(dataset);//入参打包
        setEventHead(event, 91024);
        event.setIntegerAttributeValue(EventTagdef.TAG_SENDERID, 5);//分配节点为5
        unPack(event, event.getServiceId()); //入参解包，同时打印发送包参数信息
        client.send(event);//发送包
    }

    //期货委托撤单
    public void ReqFunction819707(String user_token, String entrust_no) throws Exception {
        // 获取event
        IEvent event = ContextUtil.getServiceContext().getEventFactory()
                .getEventByAlias("819707", EventType.ET_REQUEST);
        // 往event中添加datase
        IDataset dataset = DatasetService.getDefaultInstance().getDataset();
        dataset.addColumn("user_token");//用户口令
        dataset.addColumn("contract_code");//合约代码
        dataset.addColumn("futu_exch_type");//交易类别
        dataset.addColumn("entrust_no");//委托编号
        dataset.addColumn("entrust_reference");//委托引用
        dataset.appendRow();
        dataset.updateString("user_token", user_token);
        dataset.updateString("contract_code", "");
        dataset.updateString("futu_exch_type", "");
        dataset.updateString("entrust_no", entrust_no);
        dataset.updateString("entrust_reference", "");
        event.setServiceId("819707");//打入功能号
        event.putEventData(dataset);//入参打包
        event.setIntegerAttributeValue(EventTagdef.TAG_SENDERID, 5);//分配节点为5
        setEventHead(event, 91024);
        unPack(event, event.getServiceId()); //入参解包，同时打印发送包参数信息
        client.send(event);//发送包
    }

    //期货当日委托查询
    public void ReqFunction819709(String user_token) throws Exception {
        // 获取event
        IEvent event = ContextUtil.getServiceContext().getEventFactory()
                .getEventByAlias("819709", EventType.ET_REQUEST);
        // 往event中添加datase
        IDataset dataset = DatasetService.getDefaultInstance().getDataset();
        dataset.addColumn("user_token");//用户口令
        dataset.addColumn("futu_exch_type");//交易类别
        dataset.addColumn("contract_code");//合约代码
        dataset.addColumn("entrust_no");//委托编号
        dataset.appendRow();
        dataset.updateString("user_token", user_token);
        dataset.updateString("futu_exch_type", "");
        dataset.updateString("contract_code", "");
        dataset.updateString("entrust_no", "");
        event.setServiceId("819709");//打入功能号
        event.putEventData(dataset);//入参打包
        event.setIntegerAttributeValue(EventTagdef.TAG_SENDERID, 5);//分配节点为5
        setEventHead(event, 91024);
        unPack(event, event.getServiceId()); //入参解包，同时打印发送包参数信息
        client.send(event);//发送包
    }
//期货当日成交查询

    public void ReqFunction819710(String user_token) throws Exception {
        // 获取event
        IEvent event = ContextUtil.getServiceContext().getEventFactory()
                .getEventByAlias("819710", EventType.ET_REQUEST);
        // 往event中添加datase
        IDataset dataset = DatasetService.getDefaultInstance().getDataset();
        dataset.addColumn("user_token");//用户口令
        dataset.addColumn("futu_exch_type");//操作分支机构
        dataset.addColumn("contract_code");//合约代码
        dataset.appendRow();
        dataset.updateString("user_token", user_token);
        dataset.updateString("futu_exch_type", "");
        dataset.updateString("contract_code", "");
        event.setServiceId("819710");//打入功能号
        event.putEventData(dataset);//入参打包
        event.setIntegerAttributeValue(EventTagdef.TAG_SENDERID, 5);//分配节点为5
        setEventHead(event, 91024);
        unPack(event, event.getServiceId()); //入参解包，同时打印发送包参数信息
        client.send(event);//发送包
    }

    //期货持仓查询
    public void ReqFunction819711(String user_token) throws Exception {
        // 获取event
        IEvent event = ContextUtil.getServiceContext().getEventFactory()
                .getEventByAlias("819711", EventType.ET_REQUEST);
        // 往event中添加datase
        IDataset dataset = DatasetService.getDefaultInstance().getDataset();
        dataset.addColumn("user_token");//用户口令
        dataset.addColumn("contract_code");//合约代码
        dataset.appendRow();
        dataset.updateString("user_token", user_token);
        dataset.updateString("contract_code", "");
        event.setServiceId("819711");//打入功能号
        event.putEventData(dataset);//入参打包
        event.setIntegerAttributeValue(EventTagdef.TAG_SENDERID, 5);//分配节点为5
        setEventHead(event, 91024);
        unPack(event, event.getServiceId()); //入参解包，同时打印发送包参数信息
        client.send(event);//发送包
    }

    //期货合约基本报价查询
    public void ReqFunction819475(String futu_exch_type, String commodity_type, String contract_code) throws Exception {
        // 获取event
        IEvent event = ContextUtil.getServiceContext().getEventFactory()
                .getEventByAlias("819475", EventType.ET_REQUEST);
        // 往event中添加datase
        IDataset dataset = DatasetService.getDefaultInstance().getDataset();
        dataset.addColumn("futu_exch_type");//交易类别(期货)
        dataset.addColumn("commodity_type");//品种代码类别
        dataset.addColumn("contract_code");//合约代码
        dataset.appendRow();
        dataset.updateString("futu_exch_type", futu_exch_type);
        dataset.updateString("commodity_type", commodity_type);
        dataset.updateString("contract_code", contract_code);
        event.setServiceId("819475");//打入功能号
        event.putEventData(dataset);//入参打包
        event.setIntegerAttributeValue(EventTagdef.TAG_SENDERID, 5);//分配节点为5
        setEventHead(event, 35014);
        unPack(event, event.getServiceId()); //入参解包，同时打印发送包参数信息
        client.send(event);//发送包
    }

    public void ReqFunction800050(String futu_exch_type, String commodity_type, String contract_code, String request_num) throws T2SDKException {
        IEvent event = ContextUtil.getServiceContext().getEventFactory()
                .getEventByAlias("800050", EventType.ET_REQUEST);
        // 往event中添加datase
        IDataset dataset = DatasetService.getDefaultInstance().getDataset();
        dataset.addColumn("futu_exch_type");//交易类别(期货)
        dataset.addColumn("commodity_type");//品种代码类别
        dataset.addColumn("contract_code");//合约代码
        dataset.appendRow();
        dataset.updateString("futu_exch_type", futu_exch_type);
        dataset.updateString("commodity_type", commodity_type);
        dataset.updateString("contract_code", contract_code);
        event.setServiceId("800050");//打入功能号
        event.putEventData(dataset);//入参打包
//        event.setIntegerAttributeValue(EventTagdef.TAG_SENDERID, 5);//分配节点为5
        unPackRequest(event, event.getServiceId()); //入参解包，同时打印发送包参数信息
        IEvent rEvent = client.sendReceive(event, 3000);//发送包
        unPackResponse(rEvent);
    }

    //查询日K线
    public void ReqFunction800061(String futu_exch_type, String commodity_type, String contract_code, String request_num) throws T2SDKException {
        // 获取event
        IEvent event = ContextUtil.getServiceContext().getEventFactory()
                .getEventByAlias("800061", EventType.ET_REQUEST);
        // 往event中添加datase
        IDataset dataset = DatasetService.getDefaultInstance().getDataset();
        dataset.addColumn("futu_exch_type");//交易类别(期货)
        dataset.addColumn("commodity_type");//品种代码类别
        dataset.addColumn("contract_code");//合约代码
        dataset.addColumn("request_num");//合约代码
        dataset.appendRow();
        dataset.updateString("futu_exch_type", futu_exch_type);
        dataset.updateString("commodity_type", commodity_type);
        dataset.updateString("contract_code", contract_code);
        dataset.updateString("request_num", request_num);
        event.setServiceId("800061");//打入功能号
        event.putEventData(dataset);//入参打包
//        event.setIntegerAttributeValue(EventTagdef.TAG_SENDERID, 5);//分配节点为5
        unPackRequest(event, event.getServiceId()); //入参解包，同时打印发送包参数信息
        IEvent rEvent = client.sendReceive(event, 3000);//发送包
        unPackResponse(rEvent);
    }

    //设置包头信息
    public void setEventHead(IEvent event, int compId) {
        //设置companyID
        event.setIntegerAttributeValue("71", compId);
        //设置subSystemID
        event.setIntegerAttributeValue("4", 1400);
        //设置senderCompanyID
        String[] senderArray = new String[2];
        senderArray[0] = "";
        senderArray[1] = "30058";
        event.setStringArrayAttributeValue("84", senderArray);
    }

    //业务包解包，并打印包
    public void unPack(IEvent event, String functionId) {
        StringBuilder sb = new StringBuilder();
        //获取返回集
        IDatasets result = event.getEventDatas();
        //获取结果集总数
        int datasetCount = result.getDatasetCount();
        //遍历所有的结果集
        for (int i = 0; i < datasetCount; i++) {
            //读取单个结果集信息
            IDataset ds = result.getDataset(0);
            int columnCount = ds.getColumnCount(); //获取数据数量
            //System.out.println(arg0.getServiceId());  
            //打印结果集标题
            for (int j = 1; j <= columnCount; j++) {
                sb.append(ds.getColumnName(j));
                sb.append("|");
            }
            //遍历单个结果集记录，遍历前首先将指针置到开始
            ds.beforeFirst();
            //打印结果集数据
            while (ds.hasNext()) {
                sb.append("\n");
                ds.next();
                for (int j = 1; j <= columnCount; j++) {
                    sb.append(ds.getString(j)).append("|");
                }
            }
        }
//        System.out.println("功能号" + functionId + "运行\n以下是相关入参：\n" + sb);//打印入参
    }

    private void unPackRequest(IEvent event, String functionId) {
        unPack(event);
//        System.out.println("功能号" + functionId + "运行\n以下是相关入参：\n" + result);//打印入参
    }

    //业务包解包，并打印包
    private String unPack(IEvent event) {
        StringBuilder sb = new StringBuilder();
        //获取返回集
        IDatasets result = event.getEventDatas();
        //获取结果集总数
        int datasetCount = result.getDatasetCount();
        //遍历所有的结果集
        for (int i = 0; i < datasetCount; i++) {
            //读取单个结果集信息
            IDataset ds = result.getDataset(i);
            int columnCount = ds.getColumnCount(); //获取数据数量
            //System.out.println(arg0.getServiceId());
            //打印结果集标题
            for (int j = 1; j <= columnCount; j++) {
                sb.append(ds.getColumnName(j));
                sb.append("|");
            }
            //遍历单个结果集记录，遍历前首先将指针置到开始
            ds.beforeFirst();
            //打印结果集数据
            while (ds.hasNext()) {
                sb.append("\n");
                ds.next();
                for (int j = 1; j <= columnCount; j++) {
                    sb.append(ds.getString(j)).append("|");
                }
            }
        }
        return sb.toString();
    }

    private String unPackResponse(IEvent event) {
        //判断返回值
        if (event.getReturnCode() != EventReturnCode.I_OK) {//返回错误
            StringBuilder sb = new StringBuilder();
            //获取结果集
            IDatasets result = event.getEventDatas();
            String errorInfo = event.getErrorInfo();
            if (!"".equals(errorInfo)) {
                sb.append(errorInfo);
            } else {
                //获取结果集个数
                int datasetCount = result.getDatasetCount();
                //System.out.println(event.getServiceId());
                //遍历结果集
                for (int i = 0; i < datasetCount; i++) {
                    IDataset ds = result.getDataset(i);
                    int columnCount = ds.getColumnCount();
                    //打印结果集标注
                    for (int j = 1; j <= columnCount; j++) {
                        sb.append(ds.getColumnName(j));
                        sb.append("|");
                    }
                    //遍历单个结果集记录，遍历前首先将指针置到开始
                    ds.beforeFirst();
                    while (ds.hasNext()) {
                        sb.append("\n");
                        ds.next();
                        //打印结果集数据
                        for (int j = 1; j <= columnCount; j++) {
                            sb.append(ds.getString(j)).append("|");
                        }
                    }
                }
            }
            System.err.println("以下是错误信息: \n" + sb.toString());
            return sb.toString();
        } else {
            return unPack(event);
        }
    }
}
